#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <vector>
#include "gc_ptr.h"
#include "go.h"


struct list
{
	int val;
	gc_ptr<list> next;

	list ()
	{
		val = 0;
		next = 0;
	}

	list (int v)
	{
		val = v;
		next = 0;
	}
};

void add (gc_ptr<list> &head, gc_ptr<list> elem, gc_ptr<list> cur)
{
	if (cur == 0)
		head = elem;
	else if (cur->next == NULL)
		cur->next = elem;
}

std::vector <void *> v;

void test (int STEP_COUNT, int ELEM_COUNT)
{
	for (int i = 0; i < STEP_COUNT; i++)
	{
		gc_ptr<list> head = 0;
		for (int j = 0; j < ELEM_COUNT; j++)
		{
		  list *nw = new list(rand() + j);
		  void *tmp = nw;
		  tmp = tmp - 1;
		  *((unsigned char *)tmp) = 0; //присвамваем блок таг
		  v.push_back(*((unsigned char *)tmp));
			add(head, nw, head);
		}
	}

	

	for (ptr_list *l = collect(); l != 0; l = l->next)
		go(l->ptr, 1);

	for (size_t i = 0; i < v.size(); i++)
		assert ((*((BLOCK_TAG *)v[i])).mbit == 1);	  
}

int main (int argc, char *argv[])
{
	assert(argc == 3);
	int STEP_COUNT, ELEM_COUNT;

	sscanf (argv[1], "%d", &STEP_COUNT);
	sscanf (argv[2], "%d", &ELEM_COUNT);

	test(STEP_COUNT, ELEM_COUNT);

	return 0;
}
